package com.firefly.admin.common.service.impl;

import com.firefly.admin.common.utils.AreaAddressUtil;
import com.firefly.admin.common.utils.DateUtil;
import com.firefly.admin.common.utils.DeviceUtil;
import com.firefly.admin.common.utils.IpUtil;
import com.firefly.admin.monitor.entity.FyMonitorLoginLog;
import com.firefly.admin.monitor.entity.FyMonitorOperationLog;
import com.firefly.admin.monitor.mapper.FyMonitorLoginLogMapper;
import com.firefly.admin.monitor.mapper.FyMonitorOperationLogMapper;
import lombok.extern.slf4j.Slf4j;
import com.firefly.admin.common.constant.Constants;
import com.firefly.admin.common.service.CommonLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;

@Service
@Slf4j
public class CommonLogServiceImpl implements CommonLogService {
    @Autowired
    private FyMonitorLoginLogMapper fyMonitorLoginLogMapper;
    @Autowired
    private FyMonitorOperationLogMapper fyMonitorOperationLogMapper;

    /**
     * 记录登录或登出日志
     *
     * @param request        请求
     * @param methodName     方法名
     * @param operateType    操作类型，登录、登出
     * @param operateResult  操作结果
     * @param responseResult 响应结果
     * @param requestParam   请求参数
     * @param operatorName   操作人用户名
     */
    @Override
    public void saveLoginOrLogoutLog(HttpServletRequest request, String methodName, String operateType, String operateResult, String responseResult, String requestParam, String operatorName) {
        FyMonitorLoginLog fyMonitorLoginLog = new FyMonitorLoginLog();
        fyMonitorLoginLog.setRequestUrl(request.getRequestURI());
        String localIp = IpUtil.getLocalIp(request);
        fyMonitorLoginLog.setRequestIp(localIp);
        fyMonitorLoginLog.setOperateMethod(methodName);
        fyMonitorLoginLog.setAreaAddress(AreaAddressUtil.getAreaAddress(localIp));
        fyMonitorLoginLog.setSystemName(DeviceUtil.getSystemName(request));
        fyMonitorLoginLog.setBrowserInfo(DeviceUtil.getBrowserInfo(request));
        //创建时间（操作时间）
        fyMonitorLoginLog.setOperateTime(DateUtil.getNowDate());
        fyMonitorLoginLog.setOperateType(operateType);
        fyMonitorLoginLog.setOperateResult(operateResult);
        fyMonitorLoginLog.setResponseResult(responseResult);
        fyMonitorLoginLog.setOperatorName(operatorName);
        fyMonitorLoginLog.setRequestParam(requestParam);
        fyMonitorLoginLogMapper.insert(fyMonitorLoginLog);
    }

    /**
     * 记录操作类日志
     *
     * @param request        操作请求
     * @param operateModule  操作模块
     * @param operateType    操作类型
     * @param operateDesc    操作描述
     * @param operateMethod  操作方法
     * @param operatorId     操作人ID
     * @param operateResult  操作结果
     * @param responseResult 响应结果
     * @param requestParam   请求参数
     */
    @Override
    public void saveOperateLog(HttpServletRequest request, String operateModule, String operateType, String operateDesc, String operateMethod, Long operatorId, String operateResult, String responseResult, String requestParam) {
        FyMonitorOperationLog fyMonitorOperationLog = new FyMonitorOperationLog();
        fyMonitorOperationLog.setOperateModule(operateModule);
        fyMonitorOperationLog.setOperateType(operateType);
        fyMonitorOperationLog.setOperateDesc(operateDesc);
        fyMonitorOperationLog.setRequestUrl(request.getRequestURI());
        String localIp = IpUtil.getLocalIp(request);
        //操作员ip地址
        fyMonitorOperationLog.setRequestIp(localIp);
        fyMonitorOperationLog.setOperateMethod(operateMethod);
        fyMonitorOperationLog.setOperatorId(operatorId);
        fyMonitorOperationLog.setResponseResult(responseResult);
        fyMonitorOperationLog.setOperateResult(operateResult);
        fyMonitorOperationLog.setRequestParam(requestParam);
        fyMonitorOperationLog.setAreaAddress(AreaAddressUtil.getAreaAddress(localIp));
        fyMonitorOperationLog.setSystemName(DeviceUtil.getSystemName(request));
        fyMonitorOperationLog.setBrowserInfo(DeviceUtil.getBrowserInfo(request));
        //创建时间（操作时间）
        fyMonitorOperationLog.setOperateTime(DateUtil.getNowDate());
        fyMonitorOperationLogMapper.insert(fyMonitorOperationLog);
    }

    /**
     * 系统登录记录操作日志
     *
     * @param userName 用户名
     */
    @Override
    public void saveSystemLogoutLog(String userName) {
        FyMonitorLoginLog fyMonitorLoginLog = new FyMonitorLoginLog();
        try {
            InetAddress address = InetAddress.getLocalHost();
            fyMonitorLoginLog.setRequestUrl("default");
            fyMonitorLoginLog.setRequestIp(address.getHostAddress());
            fyMonitorLoginLog.setOperateMethod("default");
            //创建时间（操作时间）
            fyMonitorLoginLog.setOperateTime(DateUtil.getNowDate());
            fyMonitorLoginLog.setOperateType(Constants.LoginOperateType.AUTO_LOGOUT);
            fyMonitorLoginLog.setOperateResult(Constants.OperateResult.SUCCESS);
            fyMonitorLoginLog.setOperatorName("system");
            fyMonitorLoginLog.setSystemName("system");
            fyMonitorLoginLog.setBrowserInfo("system");
            fyMonitorLoginLog.setResponseResult(String.format("用户[%s]登录过期，系统登出", userName));
        } catch (Exception e) {
            log.error(e.getMessage());
            fyMonitorLoginLog.setOperateResult(Constants.OperateResult.FAIL);
            fyMonitorLoginLog.setResponseResult(stackTraceToString(e.getClass().getName(), e.getMessage(), e.getStackTrace()));
        }
        fyMonitorLoginLogMapper.insert(fyMonitorLoginLog);
    }

    public String stackTraceToString(String exceptionName, String exceptionMessage, StackTraceElement[] elements) {
        StringBuilder stringBuilder = new StringBuilder();
        for (StackTraceElement element : elements) {
            stringBuilder.append(element).append("\n");
        }
        return exceptionName + ":" + exceptionMessage + "\n\t" + stringBuilder;
    }
}
